package com.weixiaodong.ModelDesign.生成实例.Prototype模式.Java中的传递;

import com.weixiaodong.ModelDesign.生成实例.Prototype模式.复制模式实例演示.Manager;

/**
 * 演示值传递
 */
class Major implements Cloneable{
    String name;

    Major(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Major{" +
                "name='" + name + '\'' +
                '}';
    }
}

class Student implements Cloneable {
    String name;

    Major major;

    Student(String name, Major major) {
        this.name = name;
        this.major = major;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", major=" + major.toString() +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class ValuePass {

    public static void funcA(int x) {
        x ++;
        System.out.println(x);
    }


    public static void funcB(Student stu) {
        stu.name = "yyy";
        stu.major.name = "xxx";
        System.out.println();
    }


    public static void funcC(Integer a) {
        a++; // 会出现自动转型，这里会从包装类转化为int类型，然后在进行++操作
        System.out.println(a);
    }

    public static void funcD(String s) {
        System.out.println(s.hashCode());
        s += "hello world";
        System.out.println(s);
    }


    public static void main(String[] args) {
        /*int x = 1;
        funcA(x);
        // 这里进行参数传递的时候，就发生了一个值拷贝，即将原型x复制了一个新的x，其作用域就会整个funcA方法体内
        System.out.println(x); // 1*/

        // 发生的起始是浅拷贝
        Student student = new Student("yyy-1", new Major("xxx-1"));
        try {
            // 深拷贝
            Student student1 = (Student) student.clone();
            student1.name = "dhaihdo";
            System.out.println(student);
            System.out.println(student1);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

        funcB(student);

        // 为什这里会发生改变? 不是会拷贝一个副本，对副本的操作会什么会影响到原型
        // 因为这里拷贝的是原型的地址，因为是引用类型
        // funcB中的形式参数stu和传递进入的实际参数指向同一个Student对象
        System.out.println(student); // Student{name='yyy', major=Major{name='xxx'}}


        Integer a = 127;
        Integer b = 129;
        funcC(a);
        funcC(b);
        System.out.println(a); // 127
        System.out.println(b); // 129

        String s = "aaa";
        System.out.println(s.hashCode()); // 相同的hashCode，String中的hashCode好像是重写过的，只要值相同，hashCode就相同
        funcD(s);
        System.out.println(s); // aaa, 在Java中String类型是引用类型，但是这里会什么没有出现上述的情况，因为存在一个String常量池
        // s.equals() 比较的是值
        System.out.println(s.equals("aaa"));  // true
        System.out.println(s.equals(new String("aaa"))); // true



    }
}
